#pragma once
#include <vector>
#include <functional>
#include <pthread.h>
#include "Sock.hpp"

using func_t = std::function<void(int)>;
class TcpServer;

class ThreadData  // 这个线程的参数,分为整个tcp的类和对应的套接字
{
public:
    ThreadData(int sock, TcpServer* server)
        :_sock(sock)
        ,_server(server)
    {}

    ~ThreadData() {}
public:
    int _sock;
    TcpServer* _server;
};


class TcpServer
{
    static void* ThreadRoutine(void* argc)
    {
        pthread_detach(pthread_self());
        ThreadData* td = (ThreadData*)argc;
        td->_server->Excute(td->_sock);
        close(td->_sock);
        delete td;
        return nullptr;
    }
public:
    TcpServer(uint16_t port, const std::string ip = "0.0.0.0")
    {
        // 创建TcpServer 并初始化
        _listensock = _sock.Socket(); // 创建套接字
        _sock.Bind(_listensock, port);  // bind
        _sock.Listen(_listensock);  // listen
    }

    void BindServer(func_t func)
    {
        _func.push_back(func);
    }

    void Excute(int sock)
    {
        for (auto& f : _func)
            f(sock);
    }

    void start()
    {
        std::string client_ip;
        uint16_t client_port;

        while (true)
        {
            int sock = _sock.Accpet(_listensock, &client_port, &client_ip);
            if (sock < 0)   continue;
            logMessage(NORMAL, "create new link success, sock: %d", sock);

            pthread_t tid;
            ThreadData* td = new ThreadData(sock, this);
            pthread_create(&tid, nullptr, ThreadRoutine, td);
        }
    }
private:
    int _listensock;
    Sock _sock;
    std::vector<func_t> _func;
};
